package com.financial.service.yspay.service.impl;


import com.alibaba.fastjson.JSON;
import com.financial.service.yspay.connector.FinancialPlatformPayFegin;
import com.financial.service.yspay.constants.FinancialYsPayReceiptWechatpayEnumConstants;
import com.financial.service.yspay.domain.FinancialYsPayReceiptWechatpayDO;
import com.financial.service.yspay.dto.FinancialYsPayDTO;
import com.financial.service.yspay.service.FinancialYsPayBuildRequestParaService;
import com.financial.service.yspay.service.FinancialYsPayReceiptWechatpayService;
import com.financial.service.yspay.service.FinancialYsPayVerifyJsonSignService;
import com.financial.service.yspay.service.FinancialYsPayWeChatPayService;
import com.financial.service.yspay.utils.DateUtils;
import com.financial.service.yspay.utils.HttpUtils;
import com.financial.service.yspay.utils.JsonUtils;
import com.financial.service.yspay.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 银盛微信支付
 *
 * @Author Vincentxin
 * @Date 2019-05-29
 */
@Service
public class FinancialYsPayWeChatPayServiceImpl implements FinancialYsPayWeChatPayService {

    private static Logger log = LoggerFactory.getLogger(FinancialYsPayWeChatPayServiceImpl.class);

    @Autowired
    private FinancialYsPayBuildRequestParaService ysBuildRequestParaService;

    @Autowired
    private FinancialYsPayVerifyJsonSignService ysVerifyJsonSignService;
    @Autowired
    private FinancialPlatformPayFegin platformPayFegin;

    /*  @Autowired
      private Producer producer;*/
    @Autowired
    private FinancialYsPayReceiptWechatpayService ysReceiptWechatpayService;
/*    @Value("${MiniAppPayNotifyUrl}")
    private String miniAppPayNotifyUrl;*/

    /**
     * 微信小程序支付
     *
     * @param paramMap
     * @return
     */
    @Override
    public Map<String, Object> miniAppPerPay(Map<String, Object> paramMap) {
        System.out.println("微信小程序支付" + JSON.toJSONString(paramMap));
        //获取平台支付通道类型
        String channelsId = paramMap.get("channelsId").toString();
        //获取平台应用标识
        String platfromId = paramMap.get("platfromId").toString();
        //交易描述
        String subject = paramMap.get("subject").toString();
        //交易金额
        String totalAmount = paramMap.get("total_amount").toString();
        //微信用户openId
        String subOpenid = paramMap.get("sub_openid").toString();
        //平台订单号
        String outTradeNo = paramMap.get("out_trade_no").toString();
        //现金支付金额
        String cashAmount = paramMap.get("cash_amount").toString();
        //营销账户支付金额
        String mer_amount = paramMap.get("mer_amount").toString();
        if (StringUtils.isBlank(subject) || StringUtils.isBlank(totalAmount)
                || StringUtils.isBlank(outTradeNo) || StringUtils.isBlank(subOpenid)
                || StringUtils.isEmpty(platfromId) || StringUtils.isEmpty(channelsId)
                || StringUtils.isEmpty(cashAmount) || StringUtils.isEmpty(mer_amount)) {
            return null;
        }
        //TODO 获取配置参数异常处理
        //根据平台支付通道类型，平台应用标识获取具体配置参数
        String ysBusiness = platformPayFegin.getYSBusiness(platfromId, channelsId);
        String parse = String.valueOf(JSON.parse(ysBusiness));
        System.out.println(parse);
        FinancialYsPayDTO ysPayDTO = JSON.parseObject(parse, FinancialYsPayDTO.class);

        Map<String, Object> realResponse = new HashMap<String, Object>();
        Map<String, String> param = new HashMap<String, String>();
        param.put("method", "ysepay.online.weixin.pay");
        param.put("partner_id", ysPayDTO.getPARTNER_ID());
        param.put("timestamp", DateUtils.getNowTimeStr());
        param.put("charset", ysPayDTO.getDEFAULT_CHARSET());
        param.put("sign_type", ysPayDTO.getSIGN_ALGORITHM());
        param.put("notify_url", "");
        param.put("version", ysPayDTO.getVERSION());
        Map<String, String> biz_contentMap = new HashMap<String, String>();

        biz_contentMap.put("out_trade_no", outTradeNo);
        biz_contentMap.put("shopdate", DateUtils.getDateFormat(new Date(), DateUtils.dtShort));
        biz_contentMap.put("subject", subject);
        biz_contentMap.put("total_amount", totalAmount);
        biz_contentMap.put("seller_id", ysPayDTO.getPARTNER_ID());
        biz_contentMap.put("seller_name", ysPayDTO.getSELLER_NAME());
        biz_contentMap.put("timeout_express", ysPayDTO.getTIMEOUT_EXPRESS());
        biz_contentMap.put("business_code", "");
        biz_contentMap.put("sub_openid", subOpenid);
        //TODO 使用枚举 （代表小程序支付）1 小程序 2或者不填代表 公众号
        biz_contentMap.put("is_minipg", "1");
        //小程序appId  或这公众共appId 看支付业务情况
        biz_contentMap.put("appid", ysPayDTO.getAPP_ID());
        if (null != paramMap.get("mer_amount") || !paramMap.get("mer_amount").equals("")) {
            biz_contentMap.put("mer_amount", paramMap.get("mer_amount").toString());
        }
        param.put("biz_content", JSON.toJSONString(biz_contentMap));
        log.info("miniAppPerPay--------------请求银盛微信支付参数" + param);
        try {
            //签名
            Map<String, String> sPara = ysBuildRequestParaService.buildRequestPara(param, ysPayDTO);
            //发起请求
            log.info("签名完成的参数：{}", sPara);
            String returnString = HttpUtils.httpsSend(ysPayDTO.getYSEPAY_GATEWAY_URL(), sPara);
            //回执参数JSON转map
            Map<String, Object> resultMap = (Map<String, Object>) JSON.parse(returnString);

            Map<String, String> obj = (Map<String, String>) resultMap.get("ysepay_online_weixin_pay_response");
            String sign = resultMap.get("sign").toString();

            realResponse.putAll(obj);
            realResponse.put("sign", sign);
            int begin = returnString.indexOf("ysepay_online_weixin_pay_response");
            String content = returnString.substring(begin);
            content = content.replace("ysepay_online_weixin_pay_response", "");
            content = content.substring(2, content.length() - 1);
            log.info("miniAppPerPay--------------调用银盛微信支付同步回执response" + content);
            //银盛同步回执信息保存
            if (null != content || !content.equals("")) {
                Map<String, Object> syncMap = JsonUtils.jsonToMap(content);
                //拼装营销优惠金额
                if (null != paramMap.get("mer_amount") || !paramMap.get("mer_amount").equals("")) {
                    syncMap.put("mer_amount", paramMap.get("mer_amount"));
                    syncMap.put("wechatpay_type", FinancialYsPayReceiptWechatpayEnumConstants.ENUM_WECHATPAYTYPE_MARKETPAY);
                } else {
                    syncMap.put("wechatpay_type", FinancialYsPayReceiptWechatpayEnumConstants.ENUM_WECHATPAYTYPE_MINIPAY);
                }
                syncMap.put("cash_amount", cashAmount);
                syncMap.put("out_trade_no", outTradeNo);
                syncMap.put("platfromId", platfromId);
                saveSyncWechatPay(syncMap);
            }
            //TODO 验证签名总是出错，需要确认一下验证签名的responseBody到底是哪些参数。
            boolean verifyResult = ysVerifyJsonSignService.verifyJsonSign(sign, content, "utf-8", ysPayDTO);
            realResponse.put("verifyResult", verifyResult);
            return realResponse;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            return realResponse;
        }
    }

    private void saveSyncWechatPay(Map<String, Object> syncMap) {
        log.error("saveSyncWechatPay-------保存同步回执信息参数" + JsonUtils.objectToJson(syncMap));
        //同步回执
        String cashAmount = syncMap.get("cash_amount").toString();
        String code = syncMap.get("code").toString();
        //code:10000只代表接口调用成功并非同步请求成功

        String outTradeNoSync = syncMap.get("out_trade_no").toString();
        String platfromId = syncMap.get("platfromId").toString();
        FinancialYsPayReceiptWechatpayDO ysReceiptWechatpayDO = new FinancialYsPayReceiptWechatpayDO();
        ysReceiptWechatpayDO.setCashAmount(new BigDecimal(cashAmount));
        String wechatpayType = syncMap.get("wechatpay_type").toString();
        try {
            //判断银盛微信支付类型 1：小程序支付 2：营销账户余额支付
            if (wechatpayType.equals(FinancialYsPayReceiptWechatpayEnumConstants.ENUM_WECHATPAYTYPE_MARKETPAY)) {
                String merAmount = syncMap.get("mer_amount").toString();
                ysReceiptWechatpayDO.setWechatpayType(wechatpayType);
                ysReceiptWechatpayDO.setMerAmount(new BigDecimal(merAmount));
            } else {
                ysReceiptWechatpayDO.setWechatpayType(wechatpayType);
            }
            if (code.equals("10000")) {
                String tradeStatusSync = syncMap.get("trade_status").toString();
                //获取回执参数
                String totalAmountSync = syncMap.get("total_amount").toString();
                String tradeNoSync = syncMap.get("trade_no").toString();
                //保存数据
                ysReceiptWechatpayDO.setGmtCreate(new Date());
                ysReceiptWechatpayDO.setGmtModified(new Date());
                ysReceiptWechatpayDO.setIsDelete(FinancialYsPayReceiptWechatpayEnumConstants.ENUM_ISDELETE_UNDEL);
                ysReceiptWechatpayDO.setOutTradeNo(outTradeNoSync);
                ysReceiptWechatpayDO.setResponseType(FinancialYsPayReceiptWechatpayEnumConstants.ENUM_RESPONSETYPE_SYNC);
                ysReceiptWechatpayDO.setTotalAmount(new BigDecimal(totalAmountSync));
                ysReceiptWechatpayDO.setTradeStatus(tradeStatusSync);
                ysReceiptWechatpayDO.setTradeNo(tradeNoSync);
                ysReceiptWechatpayDO.setWechatpayType(wechatpayType);
                ysReceiptWechatpayDO.setPlatfromAppid(platfromId);
                ysReceiptWechatpayService.save(ysReceiptWechatpayDO);
            } else {
                Object tempData = syncMap.get("trade_status");
                String tradeStatusSync = tempData != null ? tempData.toString() : "";
                //接口调用失败
                ysReceiptWechatpayDO.setOutTradeNo(outTradeNoSync);
                ysReceiptWechatpayDO.setTradeStatus(tradeStatusSync);
                ysReceiptWechatpayDO.setResponseType(FinancialYsPayReceiptWechatpayEnumConstants.ENUM_RESPONSETYPE_SYNC);
                ysReceiptWechatpayDO.setIsDelete(FinancialYsPayReceiptWechatpayEnumConstants.ENUM_ISDELETE_UNDEL);
                ysReceiptWechatpayDO.setGmtCreate(new Date());
                ysReceiptWechatpayDO.setGmtModified(new Date());
                ysReceiptWechatpayDO.setPlatfromAppid(platfromId);
                ysReceiptWechatpayService.save(ysReceiptWechatpayDO);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("支付单号：{},銀盛同步回执信息保存失败 {}", outTradeNoSync, e.getMessage());
        }
    }

    /**
     * 银盛微信异步通知回执处理
     * @param params 异步回执参数
     * @param response
     */
 /*   @Override
    public String weChatPayCallBack(Map<String,String> params ,HttpServletResponse response) {

        //TODO 验证签名
        PrintWriter out = null;
        log.info("银盛微信支付异步回执参数"+JSONUtils.objectToJson(params));

           Map<String, Object> ysBusiness = platformPayFegin.getYSBusiness(params.get("payChannelsid"), params.get("platfromAppid"));

        String businessPramJson = JSON.toJSONString(ysBusiness);
        YsPayDTO ysPayDTO=JSON.parseObject(businessPramJson, YsPayDTO.class);
        try {
            //saveAsyncWechatPay(params);
            out = response.getWriter();
            boolean res = ysVerifyJsonSignService.verifySign(params,ysPayDTO);
            log.info("签名验证情况:"+res);
            if (res){
                String msg = JSON.toJSONString(params, SerializerFeature.DisableCircularReferenceDetect);
               *//* Message message = new Message(YsReturnMQConfig.PAYTOPIC,YsReturnMQConfig.PAY_TAG,msg.getBytes());
                producer.send(message);*//*
                log.info("返回结果：SUCCESS");
                out.println("success");
               return msg;

            }else{
                log.info("返回结果：FAIL");
                out.println("fail");
            }
        }catch (Exception e){
            log.error("");
            e.printStackTrace();
        }finally {
            if (out != null){
                out.close();
            }
        }
        return null;

    }

    private void saveAsyncWechatPay(Map<String,String> params) {
        String out_trade_no = params.get("out_trade_no");
        YsReceiptWechatpayDO ysReceiptWechatpayDO = new YsReceiptWechatpayDO();
        log.error("saveAsyncWechatPay-----------保存异步回执信息参数"+JSONUtils.objectToJson(params));
        System.out.println("请求的参数"+params.toString());
        try {
            String notify_time = params.get("notify_time");
            String total_amount = params.get("total_amount");
            String trade_no = params.get("trade_no");
            String trade_status = params.get("trade_status");
            String account_date = params.get("account_date");
            ysReceiptWechatpayDO.setGmtCreate(new Date());
            ysReceiptWechatpayDO.setGmtModified(new Date());
            ysReceiptWechatpayDO.setIsDelete("1");
            ysReceiptWechatpayDO.setResponseType("2");
            ysReceiptWechatpayDO.setTradeStatus(trade_status);
            ysReceiptWechatpayDO.setOutTradeNo(out_trade_no);
            ysReceiptWechatpayDO.setTradeNo(trade_no);
            ysReceiptWechatpayDO.setTotalAmount(new BigDecimal(total_amount));
            ysReceiptWechatpayDO.setNotifyTime(notify_time);
            ysReceiptWechatpayDO.setAccountDate(account_date);
            ysReceiptWechatpayService.save(ysReceiptWechatpayDO);
            log.error("第三方支付单号：{},銀盛异步回执信息保存:{}",out_trade_no,ysReceiptWechatpayDO);
        } catch (Exception e) {
            log.error("第三方支付单号：{},銀盛异步回执信息保存失败:{}",out_trade_no,e.getMessage());
            e.printStackTrace();
        }

    }*/

}
